package com.atguigu.singleton.type7;

/**
 * @program: design-patterns
 * @author: yangshen
 * @description: type7 - 静态内部类（线程安全），推荐使用
 * 优缺点说明：
 * 1) 这种方式采用了类装载的机制来保证初始化实例时只有一个线程。
 * 2) 静态内部类方式在Singleton类被装载时并不会立即实例化，而是在需要实例化时，调用getInstance方法，才会装载SingletonInstance类，从而完成Singleton的实例化。
 * 3) 类的静态属性只会在第一次加载类的时候初始化，所以在这里，JVM帮助我们保证了线程的安全性，在类进行初始化时，别的线程是无法进入的。
 * 4) 优点：避免了线程不安全，利用静态内部类特点实现延迟加载，效率高
 * 5) 结论：推荐使用.
 * @create: 2022-01-16 11:28
 **/
public class SingleTon {

    public static void main(String[] args) {
        System.out.println("静态内部类（线程安全），推荐使用");
        //测试
        SingleTon instance1 = SingleTon.getInstance();
        SingleTon instance2 = SingleTon.getInstance();
        //true
        System.out.println(instance1 == instance2);
        System.out.println("instance1.hashCode() = "+ instance1.hashCode());
        System.out.println("instance2.hashCode() = "+ instance2.hashCode());
    }

    /**
     * 1.构造器私有化，外部不能new
     */
    private SingleTon() {
    }

    /**
     * 使用了jvm原理
     *  1.在装载SingleTon类时 SingleTonInstance类不会马上装载（实现了懒加载）
     *  2.内部类SingleTonInstance在调用的时候被jvm装载，而jvm装载类时是线程安全的，且只会装载一次
     */
    private static class SingleTonInstance{
        private static final SingleTon INSTANCE = new SingleTon();
    }

    /**
     * 3.提供一个静态的公有方法，直接返回SingletonInstance.INSTANCE
     * @return 该对象实例
     */
    public static synchronized SingleTon getInstance(){
        //装载内部类的时候，用synchronized保证了线程的安全，
        //返回的都是同一个静态属性，hashcode相同
        return SingleTonInstance.INSTANCE;
    }
}
